package com.jotta.client.dataaccess;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;

import android.content.Context;
import android.database.Cursor;
import android.os.Environment;

import com.jotta.client.communicate.Configuration;
import com.jotta.client.data.FileInfo;
import com.jotta.client.setting.SettingManager;
import com.jotta.client.utility.Utility;

public class DataAccess {

    private DBAdapter db;

    private static DataAccess instance;

    /**
     * Skeleton method
     */
    public static DataAccess getInstance() {
        if (instance == null)
            instance = new DataAccess();
        return instance;
    }

    /**
     * @return true if SD card is mounted
     */
    public boolean checkSDCardIsMounted() {
        if (android.os.Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return size of directory
     */
    public long getFileSize(File folder) {
        long foldersize = 0;

        File[] filelist = folder.listFiles();
        for (int i = 0; i < filelist.length; i++) {
            if (filelist[i].isDirectory()) {
                foldersize += getFileSize(filelist[i]);
            } else {
                foldersize += filelist[i].length();
            }
        }
        return foldersize;
    }

    /**
     * delete a file in the SD card
     *
     * @param path : the path name of the file to delete
     */
    public void deleteFileByPath(String path) {
        File file = new File(path);
        if (file.exists() && file.isFile()) {
            file.delete();
        }
    }

    /**
     * Get home folder
     *
     * @return
     */
    public File getHomeFolder() {
        String homeFolder = Configuration.INITIAL_CLIENT_PATH
                + SettingManager.getInstance().getUsername();
        File dir = new File(Environment.getExternalStorageDirectory()
                + homeFolder);
        if (!dir.exists())
            dir.mkdir();
        return dir;
    }

    /**
     * Create local file represent the sever file
     *
     * @param severPath
     * @return
     * @throws IOException
     */
    public File createLocalFile(String severPath) throws IOException {

        String slash = Configuration.SLASH;
        String filePath = Utility.convertServer2LocalFolder(severPath);
        String[] filePathFolders = filePath.split(slash);

        String reconstructPath = slash;
        for (int i = 0; i < filePathFolders.length - 1; i++) {
            reconstructPath += filePathFolders[i];
            File file = new File(reconstructPath);
            if (!file.exists()) {
                boolean success = file.mkdir();
                if (!success) {
                    throw new IOException("Could not create dir!");
                }
            }
            reconstructPath += slash;
        }

        File file = new File(filePath);
        if (!file.exists()) {
            boolean success = file.createNewFile();
            if (!success) {
                throw new IOException("Could not create file!");
            }
        } else {
            boolean success = file.delete();
            if (!success) {
                throw new IOException("Could not delete file!");
            }
            success = file.createNewFile();
            if (!success) {
                throw new IOException("Could not create file!");
            }
        }
        return file;
    }

    /**
     * Initialize database
     *
     * @param context :
     */
    public void initializeDatabase(Context context) {
        db = new DBAdapter(context);
    }

    /**
     * Auto delete service
     */
    public boolean autoDeleteService(long fileSize) {
        int i = 0;
        boolean result = false;
        long freeSpace = SettingManager.getInstance().getLocalFreeSpace();
        try {
            String value = "";
            db.open();
            Cursor m_cursor = db.getRecentFilesForAutoDelete(100);
            while ((i < 100) && (freeSpace < fileSize)) {
                value = m_cursor.getString(DBAdapter.FILE_PATH_COLUMN_INDEX);
                if (value.startsWith(getHomeFolder().getPath())) {
                    freeSpace += m_cursor
                            .getLong(DBAdapter.FILE_SIZE_COLUMN_INDEX);
                    db.deleteFileByPathName(value);
                    deleteFileByPath(value);
                }
                i++;
            }
            m_cursor.close();
            db.close();
            if (freeSpace >= fileSize)
                result = true;
        } catch (Exception e) {
            result = false;
        }
        return result;
    }

    /**
     * Get latest revision of file
     *
     * @param path : path file
     * @return: latest revision
     */
    public int getLatestRevisionOfFile(String path) {
        try {
            int value = 0;
            db.open();
            Cursor m_cursor = db.getFilesByName(path);
            value = m_cursor.getInt(DBAdapter.FILE_REVISION_COLUMN_INDEX);
            m_cursor.close();
            db.close();
            return value;
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * Recored new file info into database
     *
     * @param fileInfo : file downloaded
     */
    public void recordNewFileIntoDatabase(FileInfo fileInfo) {
        try {
            String localPathFile = fileInfo.getLocalPathOfItem();
            db.open();
            db.deleteFileByPathName(localPathFile);
            db.insertFile(fileInfo.getLocalPathOfItem(), fileInfo
                    .getCurrentRevionsNumber(), fileInfo.getFileSize(), 1,
                    Calendar.getInstance().getTime());
            db.close();
        } catch (Exception e) {

        }
    }

    /**
     * Increase number of active info
     *
     * @param fileInfo
     */
    public void increaseNumberOfActive(FileInfo fileInfo) {
        try {
            String localPathFile = fileInfo.getLocalPathOfItem();
            db.open();
            Cursor cursor = db.getFilesByName(localPathFile);
            long rowId = cursor.getLong(DBAdapter.ROW_ID_COLUMN_INDEX);
            int numOfActive = cursor
                    .getInt(DBAdapter.NUM_OF_ACTIVE_COLUMN_INDEX);
            db.updateNumberOfActiveFileInfo(rowId, numOfActive + 1);
            cursor.close();
            db.close();
        } catch (Exception e) {

        }
    }
}
